package top.bug.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.bug.blog.entity.po.SysConfig;
import top.bug.blog.mapper.SysConfigMapper;
import top.bug.blog.service.SysConfigService;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author <a href="https://github.com/jiusi66">九思.</a>
 * @email 10837907@qq.com
 * @from <a href="https://www.52bug.top">递归茶馆-www.52bug.top</a>
 * @description 系统配置 实现类
 */
@Service
@Slf4j
public class SysConfigServiceImpl implements SysConfigService {

    @Resource
    private SysConfigMapper configMapper;

    /**
     * Caffeine缓存配置：最大100条，10分钟刷新
     */
    private final Cache<String, String> configCache = Caffeine.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

    /**
     * 获取所有配置
     */
    @Override
    public Map<String, String> getAllConfigs() {
        List<SysConfig> configs = configMapper.selectList(new LambdaQueryWrapper<SysConfig>()
                .select(SysConfig::getConfigKey, SysConfig::getConfigValue)
        );

        return configs.stream().collect(
                Collectors.toMap(SysConfig::getConfigKey, SysConfig::getConfigValue));
    }

    /**
     * 批量更新配置
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateConfigs(Map<String, String> configMap) {
        configMap.forEach((key, value) -> {
            int count = configMapper.update(null,
                    new LambdaUpdateWrapper<SysConfig>()
                            .set(SysConfig::getConfigValue, value)
                            .eq(SysConfig::getConfigKey, key));

            if (count == 0) {
                // 新建配置
                SysConfig newConfig = new SysConfig();
                newConfig.setConfigKey(key);
                newConfig.setConfigValue(value);
                configMapper.insert(newConfig);
            }

            // 更新缓存
            configCache.put(key, value);
        });

        return true;
    }

    /**
     * 获取单个配置（带缓存）
     */
    @Override
    public String getConfigValue(String key) {
        return configCache.get(key, k ->
                Optional.ofNullable(configMapper.selectValueByKey(k)).orElse("")
        );
    }

    /**
     * 刷新缓存
     */
    @Override
    public void refreshCache() {
        configCache.invalidateAll();
        Map<String, String> configs = getAllConfigs();
        configs.forEach(configCache::put);
    }
}